import {SimpleFunction} from "@peryl/react-compose";
import {defer, DFD} from "@peryl/utils/defer";
import {PlainObject} from "@peryl/utils/event";
import {microApp} from "../../../microApp";
import {buildAssetsPath} from "../../../common/buildAssetsPath";

interface iMonacoRequireFunction {
  (deps: string[], handler: (modules: any[]) => void): void,

  config: SimpleFunction
}

// const MONACO_LOADER_PATH = "https://cdn.bootcdn.net/ajax/libs/monaco-editor/0.34.1/min/vs/loader.min.js";
// const MONACO_VS_PATH = "https://cdn.bootcdn.net/ajax/libs/monaco-editor/0.34.1/min/vs";

export const MonacoLoader = (() => {

  const MONACO_LOADER_PATH = buildAssetsPath("libs/monaco-editor/0.34.1/min/vs/loader.min.js");
  const MONACO_VS_PATH = buildAssetsPath("libs/monaco-editor/0.34.1/min/vs");

  /**
   * 加载monaco中的loader函数
   * @author  韦胜健
   * @date    2023/2/10 9:49
   */
  const getMonacoRequire = (() => {
    let monacoRequire = null as null | iMonacoRequireFunction;
    return async (): Promise<iMonacoRequireFunction> => {
      if (!!monacoRequire) {
        return monacoRequire;
      }
      return new Promise((resolve, reject) => {
        const scriptEl = document.createElement('script');
        scriptEl.onload = () => {
          monacoRequire = window.require as any;
          if (!!monacoRequire) {
            resolve(monacoRequire);
          } else {
            alert('加载monaco-editor/loader失败！');
            reject('window.require not exist!');
          }
        };
        scriptEl.onerror = (error) => {
          alert('加载monaco-editor/loader失败！');
          reject(error);
        };
        scriptEl.src = MONACO_LOADER_PATH;
        document.body.appendChild(scriptEl);
      });
    };
  })();

  let getMonacoDefer: DFD<PlainObject> | undefined = undefined;

  const getMonaco = () => {
    if (!getMonacoDefer) {
      getMonacoDefer = defer<PlainObject>();
      /**
       * 先加载babel相关的依赖再去加载monaco，不然babel后加载的话好像会编译monaco的代码导致报错
       * @author  韦胜健
       * @date    2023/2/10 10:01
       */
      microApp.resource.load('babel', window).then(() => {
        getMonacoRequire().then(monacoRequire => {
          monacoRequire.config({ paths: { vs: MONACO_VS_PATH } });
          monacoRequire([
            'vs/editor/editor.main'
          ], (monaco) => {
            if (!!monaco) {
              getMonacoDefer!.resolve(monaco);
            } else {
              alert('load monaco failed!');
              getMonacoDefer!.reject('load monaco failed!');
            }
          });
        });
      });
    }
    return getMonacoDefer.promise;
  };

  return { getMonaco };
})();
